using Microsoft.Extensions.Logging;
using SumerCoreDevOps.Infrastructure.Tcp;
using SumerCoreDevOps.Shared.Enums;
using SumerCoreDevOps.Shared.Models.Messages;
using SumerCoreDevOps.ExecuteNodeApi.Handlers;
using TaskStatus = SumerCoreDevOps.Shared.Enums.TaskStatus;

namespace SumerCoreDevOps.ExecuteNodeApi.Services;

/// <summary>
/// 任务执行器
/// </summary>
public class TaskExecutor
{
    private readonly ILogger<TaskExecutor> _logger;
    private readonly TcpClient _tcpClient;
    private readonly HeartbeatService _heartbeatService;
    private readonly IServiceProvider _serviceProvider;

    public TaskExecutor(
        ILogger<TaskExecutor> logger,
        TcpClient tcpClient,
        HeartbeatService heartbeatService,
        IServiceProvider serviceProvider)
    {
        _logger = logger;
        _tcpClient = tcpClient;
        _heartbeatService = heartbeatService;
        _serviceProvider = serviceProvider;
    }

    /// <summary>
    /// 执行任务
    /// </summary>
    public async Task ExecuteTaskAsync(WorkflowStepDispatchMessage message)
    {
        _heartbeatService.IncrementTaskCount();

        try
        {
            _logger.LogInformation("开始执行任务: TaskId={TaskId}, StepType={StepType}",
                message.TaskId, message.StepType);

            // 上报开始状态
            await ReportStatusAsync(message.TaskId, message.StepId, TaskStatus.Running, 0);

            // 根据步骤类型选择处理器
            var handler = GetHandler(message.StepType);

            if (handler == null)
            {
                _logger.LogError("未找到步骤类型 {StepType} 的处理器", message.StepType);
                await ReportStatusAsync(
                    message.TaskId,
                    message.StepId,
                    TaskStatus.Failed,
                    0,
                    $"不支持的步骤类型: {message.StepType}");
                return;
            }

            // 执行任务
            var result = await handler.ExecuteAsync(message);

            // 上报结果
            if (result.Success)
            {
                await ReportStatusAsync(
                    message.TaskId,
                    message.StepId,
                    TaskStatus.Success,
                    100,
                    null,
                    result.OutputContext);

                _logger.LogInformation("任务执行成功: TaskId={TaskId}", message.TaskId);
            }
            else
            {
                await ReportStatusAsync(
                    message.TaskId,
                    message.StepId,
                    TaskStatus.Failed,
                    result.Progress,
                    result.ErrorMessage);

                _logger.LogError("任务执行失败: TaskId={TaskId}, Error={Error}",
                    message.TaskId, result.ErrorMessage);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "任务执行异常: TaskId={TaskId}", message.TaskId);

            await ReportStatusAsync(
                message.TaskId,
                message.StepId,
                TaskStatus.Failed,
                0,
                $"任务执行异常: {ex.Message}");
        }
        finally
        {
            _heartbeatService.DecrementTaskCount();
        }
    }

    /// <summary>
    /// 上报状态
    /// </summary>
    private async Task ReportStatusAsync(
        long taskId,
        long stepId,
        TaskStatus status,
        int progress,
        string? errorMessage = null,
        Dictionary<string, string>? outputContext = null)
    {
        var report = new StepStatusReportMessage
        {
            TaskId = taskId,
            StepId = stepId,
            Status = status,
            Progress = progress,
            ErrorMessage = errorMessage,
            OutputContext = outputContext ?? [],
            StartTime = status == TaskStatus.Running ? DateTime.UtcNow : null,
            EndTime = status == TaskStatus.Success || status == TaskStatus.Failed ? DateTime.UtcNow : null
        };

        await _tcpClient.SendMessageAsync(TcpMessageType.StepStatusReport, report);
    }

    /// <summary>
    /// 发送日志流
    /// </summary>
    public async Task SendLogAsync(long taskId, long stepId, string message, string level = "Info")
    {
        try
        {
            var logMsg = new LogStreamMessage
            {
                TaskId = taskId,
                StepId = stepId,
                LogContent = message,
                LogLevel = level,
                Timestamp = DateTime.UtcNow,
                IsEnd = false
            };

            await _tcpClient.SendMessageAsync(TcpMessageType.LogStream, logMsg);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "发送日志流失败: {Message}", message);
        }
    }

    /// <summary>
    /// 获取处理器
    /// </summary>
    private IStepHandler? GetHandler(StepType stepType)
    {
        return stepType switch
        {
            StepType.GitClone => _serviceProvider.GetService<GitCloneHandler>(),
            StepType.Build => _serviceProvider.GetService<BuildHandler>(),
            StepType.Test => _serviceProvider.GetService<TestHandler>(),
            StepType.DeployDocker => _serviceProvider.GetService<DeployDockerHandler>(),
            StepType.DeployK8s => _serviceProvider.GetService<DeployK8sHandler>(),
            StepType.Cleanup => _serviceProvider.GetService<CleanupHandler>(),
            StepType.DockerDeployRemote => _serviceProvider.GetService<DockerDeployRemoteHandler>(),
            StepType.ArchiveArtifacts => _serviceProvider.GetService<ArchiveArtifactsHandler>(),
            _ => null
        };
    }
}
